﻿using System;
using System.Collections.Generic;
using STeaL.Functional;

namespace STeaL.Algorithm {
  public static partial class IListExtensions {
#region unique
    public static int unique<T>(this IList<T> list, int first, int last, Func<T,T,bool> pred ) {
      if ( first != last ) {
        for ( int firstb = first; ++first != last; ++firstb)
          if ( pred(list[firstb], list[first] ) ) {
            while ( ++first != last ) 
              if ( !pred(list[firstb],list[first]) ) list[++firstb] = list[first];
            return ++firstb;
          }
      }
      return last;
    }

    public static int unique<T>(this IList<T> list, int first, int last) where T : IComparable<T> {
      return unique(list, first, last, rel_op.equal_to<T>);
    }

    public static int unique<T>(this IList<T> list, Func<T,T,bool> pred ) {
      return unique(list, 0, list.Count, pred);
    }

    public static int unique<T>(this IList<T> list) where T : IComparable<T> {
      return unique(list, 0, list.Count, rel_op.equal_to<T>);
    }

#endregion
#region unique_copy
    public static IEnumerable<T> unique_copy<T>(this IList<T> list, int first, int last, Func<T,T,bool> pred) {
      if ( first != last ) {
        T val = list[first];
        yield return val;
        while ( ++first != last ) {
          if ( !pred(val, list[first]) ) {
            val = list[first];
            yield return val;
          }
        }
      }
      yield break;
    }

    public static IEnumerable<T> unique_copy<T>(this IList<T> list, Func<T,T,bool> pred) {
      return unique_copy(list, 0, list.Count, pred);
    }

    public static IEnumerable<T> unique_copy<T>(this IList<T> list, int first, int last) where T : IComparable<T> {
      return unique_copy(list, first, last, rel_op.equal_to<T>);
    }

    public static IEnumerable<T> unique_copy<T>(this IList<T> list) where T : IComparable<T> {
      return unique_copy(list, 0, list.Count, rel_op.equal_to<T>);
    }

#endregion
  }
}
